import socket
import datetime
import pymysql
import requests
from collections import deque

# bark keys list
bark_keys = [
    'wXMCSCnZVj8NtsKzbjYrq7'
    # 'NRCGdyL8bDe42bMBxhyNa5',
    # 'UcxV3324SVnnKGMTQVsbhP',
    # 'AiZgi2NBwJXDoSVYwCKKLg',
    # 'Zu77cCAZTnvEMeFzuB74Fm'
]

# 过滤条件
filter_ok_words = [
    '白条', '立减金', "还款", "话费", "数字币", "数币", "数字人民币", "和包", "建行生活", "支付宝", "支付", "建行",
    "建行生活", "云闪付", "移动", "联通", "电信", "E卡", "京东E卡", "建行", "和包", "分分卡", "打卡", "签到", "小金库",
    "地铁",
    "大都会", "盒马", "体验金", "沃钱包", "速度", "大水", "小水", "大毛", "小毛", "手慢无", "1元", "麦当劳", "集卡",
    "zfb", "ysf",
    "邮储", "邮政", "动卡空间", "中信", "平安", "平安口袋银行", "兴业", "交通", "买单吧", "浦发", "浦大喜奔", "广发",
    "发现精彩",
    "民生", "全民生活", "e生活", "工银e生活", "工商银行", "工行", "工银兴农通", "招商", "掌上生活", "光大",
    "阳光惠生活", "中行", "中国银行",
    "中银跨境", "朴朴", "翼支付", "yzf", "抽奖"
]
filter_not_words = ["为什么", "怎么", "为啥", "?", "？", "能不能", "可以吗", "可以不", "好价", "联盟", "吗", "呢"]

search_times = 0
today_count = 0
max_id = 0
last_max_id = 0
new_data_list = []
webPrefix = 'http://new.xianbao.fun'
# 创建一个最大长度为20的双端队列
pushed_messages = deque(maxlen=20)


def mysql_db():
    conn = pymysql.connect(
        host='101.132.157.214',
        port=3306,
        database='alarm',
        charset='utf8',
        user='alarm',
        password='Tian201404293'
    )
    return conn


# 获取本机IP
def get_local_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP


# 获取数据库中的所有代理IP
def get_proxies_from_db(conn):
    cur = conn.cursor()
    cur.execute("SELECT ip FROM proxies")
    return [row[0] for row in cur.fetchall()]


# 获取上次最大ID
def get_last_max_id_from_db(conn):
    # 创建游标对象
    cursor = conn.cursor()

    # 查询最新的 last_max_id
    query = "SELECT last_max_id FROM message_id_records LIMIT 1"
    cursor.execute(query)
    result = cursor.fetchone()

    if result:
        last_max_id = result[0]
        print(f"最新的 last_max_id 是: {last_max_id}")
        return last_max_id
    else:
        print("表中没有记录或出现错误。")
        # return None
        return 0


# 更新消息最大ID记录
def update_last_max_id_to_db(conn, last_max_id):
    # 创建游标对象
    cursor = conn.cursor()

    # 更新数据库中的 last_max_id
    update_query = "UPDATE message_id_records SET last_max_id = %s"
    cursor.execute(update_query, (last_max_id,))
    conn.commit()

    print(f"已成功更新数据库中的 last_max_id 为: {last_max_id}")

    # 关闭游标
    cursor.close()


# 获取线报信息
def get_data(conn):
    url = "http://new.xianbao.fun/plus/json/push.json"
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Cache-Control': 'max-age=0',
        'Cookie': 'timezone=8',
        'If-Modified-Since': 'Sun, 12 Nov 2023 13:23:59 GMT',
        'If-None-Match': '"6550d1ef-1fd0"',
        'Proxy-Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.68'
    }
    try:
        response = requests.get(url, headers=headers, timeout=5)  # 设置超时时间为5秒
        response.raise_for_status()  # 检查是否有错误
    except requests.exceptions.RequestException as e:
        print(f"请求失败：{e}")
        return None
    # 检查服务器的响应是否可以被解析为JSON
    try:
        data_list = response.json()
    except (ValueError, Exception) as e:  # 捕获所有可能的异常
        return None  # 如果发生错误，直接返回None
    # 如果data_list为空，直接返回
    if not data_list:
        return None
    # 判断data_list是否是一个list(修复问题：客户端返回{'code': '0x01900012', 'message': 'cannot find token param.'})
    if isinstance(data_list, dict):
        return None
    # 找到本次数据列表中的最小ID和最大ID
    current_min_id = min(int(item['id']) for item in data_list)
    current_max_id = max(int(item['id']) for item in data_list)
    # 查询数据库获取上一次的最大ID
    last_max_id = get_last_max_id_from_db(conn)
    # 如果本次最小ID大于等于上次的最大ID，只返回ID大于上一次查询的最大ID的数据
    if current_min_id >= last_max_id:
        new_data_list = [item for item in data_list if item['id'] > last_max_id]
        last_max_id = current_max_id
        # 调用 update_last_max_id_to_db 函数
        update_last_max_id_to_db(conn, last_max_id)
    # 否则，只返回ID大于上一次查询的最大ID的数据
    else:
        if current_max_id <= last_max_id:
            new_data_list = []
            print("上次最大ID和本次最大ID一样")
        else:
            new_data_list = [item for item in data_list if item['id'] > last_max_id]
            last_max_id = current_max_id
            # 调用 update_last_max_id_to_db 函数
            update_last_max_id_to_db(conn, last_max_id)

    return new_data_list


# 线报过滤
def filter_data(data, filter_ok_words, filter_not_words):
    # 过滤数据，先筛选出包含filter_ok_words的数据，再过滤掉包含filter_not_words的数据
    result = []
    # print("【1】过滤前的线报列表list=", data)
    for item in data:
        if any(f in item['title'] or f in item['content'] for f in filter_ok_words):
            if not any(f in item['title'] or f in item['content'] for f in filter_not_words):
                result.append(item)
    return result


# bark推送
def send_bark_notification(id, title, content, url):
    # bark_keys = ['wXMCSCnZVj8NtsKzbjYrq7']
    formatted_title = f"【{id}】{title}"
    # 获取当前的小时数
    current_hour = datetime.datetime.now().hour
    # 如果当前的小时数在0到7之间，不设置铃声；否则，设置铃声为'bell'
    sound = 'bell' if 7 <= current_hour < 24 else ''
    # 遍历所有的bark_key
    send_code = 0
    for bark_key in bark_keys:
        # 构造请求的URL
        request_url = f"https://api.day.app/{bark_key}/{title}/{content}?url={webPrefix + url}&sound={sound}"
        # print("【request_url】=", request_url)
        # 发送请求
        try:
            response = requests.get(request_url)
            # 检查请求是否成功
            if response.status_code == 200:
                send_code = 1
                continue
        except requests.exceptions.ConnectionError:
            continue
    return send_code


if __name__ == '__main__':
    print('😉😉😉来咯来咯他来咯，抓取开始......')
    # 创建DB链接
    conn = mysql_db()
    # 线报列表
    list = get_data(conn)
    if list is None:
        exit()
    nice_list = filter_data(list, filter_ok_words, filter_not_words)
    print("【2】过滤后的线报列表nice_list=", nice_list)
    # 遍历nice_list，并对每个元素发送通知
    success_count = 0
    for item in nice_list:
        title = item['title']
        content = item['content']
        # bark推送
        success_count += send_bark_notification(item['id'], item['title'], item['content'], item['url'])
    today_count = today_count + success_count
    run_log = f"💃本次拉取：{len(list)}条，符合条件：{len(nice_list)}条，成功推送：{success_count}条......"
    print(run_log)
